package cn.falcon.fmobi.console.aop;

import cn.falcon.fmobi.biz.exception.AdvertiserValidateException;
import cn.falcon.fmobi.biz.exception.CreativeValidateException;
import cn.falcon.fmobi.biz.exception.CampaignValidateException;
import cn.falcon.fmobi.console.common.RestfulJsonModelAndView;
import cn.falcon.fmobi.console.common.Result;
import cn.falcon.fmobi.console.exception.CallBackException;
import cn.falcon.fmobi.console.exception.ParamValidateException;
import cn.falcon.fmobi.console.exception.PermissionRefuseException;
import cn.falcon.marketing.api.exception.MarketingException;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import javax.security.auth.login.AccountException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author dongbin.yu
 * @from 2016-04-11
 * @since V1.0
 */
@ControllerAdvice
public class ControllerExceptionHandler {

    Logger logger = org.slf4j.LoggerFactory.getLogger(getClass());

    @Autowired
    MessageSource messageSource;

    @ExceptionHandler(value = { Exception.class })
    @ResponseBody
    public ModelAndView defaultExceptionHandle(Exception ex) {
        ex.printStackTrace();
        return RestfulJsonModelAndView.buildError(Result.ERR_INNER_SERVER,
            messageSource.getMessage("Result.err.system", new Object[] {}, LocaleContextHolder.getLocale()),
            ex.getMessage());
    }

    /**
     * 处理 CallBackException
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = { CallBackException.class })
    @ResponseBody
    public ModelAndView callBackExceptionHandle(CallBackException ex) {
        ResultCode resultCode = ResultCode.forValue(ex.getErrCode());
        return RestfulJsonModelAndView
            .buildError(resultCode.getValue(),
                messageSource.getMessage(resultCode.getDesc(), new Object[] {}, LocaleContextHolder.getLocale()),
                ex.getMessage());
    }

    /**
     * 处理参数异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = { ParamValidateException.class })
    @ResponseBody
    public ModelAndView ParamsValidateExceptionHandle(ParamValidateException ex) {
        return RestfulJsonModelAndView.buildError(ex.getErrCode(), messageSource
                .getMessage(ex.getMessage(), new Object[] { ex.getParamName() }, LocaleContextHolder.getLocale()),
            ex.getMessage());
    }

    /**
     * 处理 Marketing API Exception
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(value = { MarketingException.class })
    @ResponseBody
    public MappingJackson2JsonView gdtExceptionHandle(MarketingException ex) {
        MappingJackson2JsonView jsonView = new MappingJackson2JsonView();
        Map<String, String> map = new HashMap<>();
        logger.error(
            "Marketing API Error:" + ex.getError().getCode() + ":" + ex.getError().getMsg() + ";" + ex.getMessage());
        map.put("ret", "G" + ex.getError().getCode());
        map.put("err_msg", ex.getError().getMsg());
        map.put("exception", ex.getMessage());
        jsonView.setAttributesMap(map);
        return jsonView;
    }

    @ExceptionHandler(value = { PermissionRefuseException.class })
    public ModelAndView permissionRefuseExceptionHandle(PermissionRefuseException ex) {
        return RestfulJsonModelAndView.buildError(Result.ERR_TOKEN_EXPIRED,"invalid login user","invalid login user");
    }

    @ExceptionHandler(value = CreativeValidateException.class)
    public ModelAndView creativeValidateExceptionHandler(CreativeValidateException ex){
        ResultCode resultCode = ResultCode.forValue(ex.getCode().getValue());
        return RestfulJsonModelAndView
                .buildError(resultCode.getValue(),
                        messageSource.getMessage(resultCode.getDesc(), new Object[] {}, LocaleContextHolder.getLocale()),
                        ex.getMessage());
    }

    @ExceptionHandler(value = { AccountException.class })
    public ModelAndView accountExceptionHandle(AccountException ex) {
        return RestfulJsonModelAndView.buildError(ResultCode.USER_CREATE_UPDATE_ERROR.getValue(),ex.getMessage(),ex.getMessage());
    }

    @ExceptionHandler(CampaignValidateException.class)
    @ResponseBody
    public ModelAndView campaignValidateExceptionHandle(CampaignValidateException ex) {
        ResultCode resultCode = ResultCode.forValue(ex.getCode().getValue());
        return RestfulJsonModelAndView.buildError(resultCode.getValue(), messageSource
            .getMessage(resultCode.getDesc(), new Object[] { ex.getMin(), ex.getMax() },
                LocaleContextHolder.getLocale()), null);
    }

    @ExceptionHandler(value = AdvertiserValidateException.class)
    @ResponseBody
    public ModelAndView advertiserValidateExceptionHandler(AdvertiserValidateException ex) {
        ResultCode resultCode = ResultCode.forValue(ex.getCode().getValue());
        return RestfulJsonModelAndView
            .buildError(resultCode.getValue(),
                messageSource.getMessage(resultCode.getDesc(), new Object[] {}, LocaleContextHolder.getLocale()),
                ex.getMessage());
    }

}
